package com.heriparid.slideshow.paging;

import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Handler;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;

import com.heriparid.slideshow.R;
import com.heriparid.slideshow.model.PhotoHolder;
import com.heriparid.slideshow.sound.SoundManager;
import com.heriparid.slideshow.util.ImageResourceLoader;

@SuppressLint("NewApi")
public class PageManager implements ViewPager.OnPageChangeListener, OnSwipeTouchListener.OnSingleTapListener {

	public enum PageDirection {
		LEFT,
		RIGHT
	}
	
	private enum SoundPlayType {
		SOUND,
		DESCSOUND,
		SOUND_AND_DESCSOUND
	}
	
	private static final String TAG = PageManager.class.getSimpleName();
	private Context mContext;
	private CustomViewPager mViewPager;	
	
	// Page indexes for 3 pages.
	public static final int PAGE_LEFT = 0;
	public static final int PAGE_MIDDLE = 1;
	public static final int PAGE_RIGHT = 2;
	
	// SlideShow
	private static final int SLIDESHOW_INTERVAL = 7000;
	private static final int SLIDESHOW_SOUND_QUEUE = 2000;
		
	public static PageContainer[] PAGE_CONTAINER = new PageContainer[3];
	private List<PhotoHolder> mPhotoHolders;
	private int mSelectedPosition = PAGE_MIDDLE;
	
	// Image loader
	private ImageResourceLoader mImageResourceLoader = ImageResourceLoader.createInstance();
	
	// Sound
	private final SoundManager mSoundManager;
	
	private Handler mHandler = new Handler();
	private boolean isSlideShowFired = false;
		
	public PageManager(Context context, CustomViewPager viewPager, List<PhotoHolder> photoHolders) {
		mContext = context;
		mViewPager = viewPager;		
		mPhotoHolders = photoHolders;
		
		mViewPager.setOnPageChangeListener(this);
		mViewPager.setOnTouchListener(new OnSwipeTouchListener(this));
		
		mSoundManager = new SoundManager(mContext);		
	}	
	
	private Runnable mStartSlideShow = new Runnable() {		
	
		@Override
		public void run() {
			mViewPager.setCurrentItem(PAGE_RIGHT, true);		
			mHandler.postDelayed(mStartSlideShow, SLIDESHOW_INTERVAL);
		}
	};
	
	public void init(){
		
		final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);	
		
		for (int i = 0; i < PAGE_CONTAINER.length; i++) {				
			// initiating the PageContainer with indexes of last-page, first-page and second-page
			View view = inflater.inflate(R.layout.page_content_layout, null);
			
			PageContainer page = new PageContainer(adjustIndexLimit(i-1));
			page.view = view;
			
			PhotoHolder photo = mPhotoHolders.get(page.getIndex());
			
			page.setPageContent(photo.getTitle(), 
					mImageResourceLoader.getOrCreateBitmapFromResource(mContext.getResources(), photo.getImageResourceId()));
			
			PAGE_CONTAINER[i] = page;
		}
		
		// Load Sounds
		for(PhotoHolder photo : mPhotoHolders){			
			mSoundManager.addSound(photo.getSoundResourceId());
			mSoundManager.addSound(photo.getDescSoundResourceId());			
		}	
	}

	@Override
	public void onPageScrollStateChanged(int state) {
		if (state == ViewPager.SCROLL_STATE_IDLE) {			
			switch (mSelectedPosition) {
			case PAGE_LEFT:
				// user swiped to right direction --> left page
				updatePages(PageDirection.LEFT);				
				break;
			case PAGE_RIGHT:
				// user swiped to left direction --> right page
				updatePages(PageDirection.RIGHT);				
				break;
			}							
		}
	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		
	}

	@Override
	public void onPageSelected(int position) {
//		Log.i(TAG, "selected page " + position);
		mSelectedPosition = position;	
	}
	
	@Override
	public void onSingleTap(MotionEvent event) {
//		Log.i(TAG, "onSingleTap");	
		if(!isSlideShowFired){
			playSound(SoundPlayType.SOUND);
		}
		
	}
	
	private int adjustIndexLimit(int index){
		if(index > mPhotoHolders.size() - 1){
			return 0;			
		}else if(index < 0)
			return mPhotoHolders.size() - 1;
		
		return index;
	}
	
	private void reIndexPage(PageContainer page, PageDirection direction){
		int currentIdx = page.getIndex();
		switch (direction) {
			case LEFT: currentIdx--; break;
			case RIGHT:currentIdx++; break;		
		}
		
		currentIdx = adjustIndexLimit(currentIdx);		
		page.setIndex(currentIdx);
	}
	
	public void updatePages(PageDirection direction){
		
//		Log.i(TAG, "updatePages to " + direction.toString());	
		
		for (int i = 0; i < PAGE_CONTAINER.length; i++) {				
			PageContainer page = PAGE_CONTAINER[i];
			reIndexPage(page, direction);
			
			PhotoHolder photo = mPhotoHolders.get(page.getIndex());
			
			page.setPageContent(photo.getTitle(), 
					mImageResourceLoader.getOrCreateBitmapFromResource(mContext.getResources(), photo.getImageResourceId()));
		}
		
		playSound(isSlideShowFired ? SoundPlayType.SOUND_AND_DESCSOUND : SoundPlayType.DESCSOUND);
		
		// Recreate Item		
		mViewPager.getAdapter().notifyDataSetChanged();		
		mViewPager.setCurrentItem(PAGE_MIDDLE, false);
	}
	
	public void playCurrentSound(){
		playSound(SoundPlayType.DESCSOUND);
	}
	
	private void playSound(SoundPlayType type) {
		
		PageContainer container = PAGE_CONTAINER[PAGE_MIDDLE];		
		int index = container.getIndex();
		
		PhotoHolder holder = mPhotoHolders.get(index);
		final int soundResId = holder.getSoundResourceId();
		final int descSoundResId = holder.getDescSoundResourceId();
		
		switch (type) {
		case DESCSOUND:
			mSoundManager.playSound(descSoundResId);
			break;
		case SOUND:
			mSoundManager.playSound(soundResId);
			break;
		case SOUND_AND_DESCSOUND:
			mSoundManager.playSound(descSoundResId);
			mHandler.postDelayed(new Runnable() {				
				@Override
				public void run() {
					mSoundManager.playSound(soundResId);
				}
			}, SLIDESHOW_SOUND_QUEUE);
			break;
		}	
	}

	public void startSlideShow(){
		if(!isSlideShowFired){
			mHandler.post(mStartSlideShow);
			
			isSlideShowFired = true;
			mViewPager.setPagingEnabled(false);
		}
		
	}
	
	public void stopSlideShow(){
		if(isSlideShowFired){
			mHandler.removeCallbacks(mStartSlideShow);
			isSlideShowFired = false;
			mViewPager.setPagingEnabled(true);
		}
	}
	
	public void clearResources(){
		
		mSoundManager.clearSoundPool();
	}
	
}
